HI!大家好,我是 Shammi 😊
關於Gemini-1.5-Flash模型即將不再支援了!
但因還在挑戰時間裡,所以後續會再逐步更改程式碼並再繼續測試與精進此專案內容,先跟讀者們抱歉><
說實在這也是做專案會遇到的問題!AI的迭代速度真的太快了!不得不說完成專案的速度很難抓啊
模組的更改,我也會再部署至雲端時再說明哦!
好的,繼續說下去。
在先前的挑戰篇幅中,已經建立並運行了 LINE 機器人。然而,在 Google Colab 這種單一環境下,管理多個長時間運行的服務(如 LINE Bot 和未來將開發的 Telegram Bot),會遇到一些特定的挑戰。
本篇將作為一個完整的學習單元,深入理解這些挑戰,並透過一個包含所有必要步驟的 LINE 機器人實作範例,解釋如何在 Colab 中管理單一平台機器人專案。
Colab 是一個非常適合快速開發和測試的平台,但它並非為 24/7 持續運行多個後台服務而設計。因此,我們需要理解並應對其固有的一些挑戰:
1️⃣ 埠號(Port)佔用衝突 🔌
LINE Bot 核心基於 Flask 框架,它會啟動一個 Web 伺服器並佔用特定的網路埠(例如 5000 埠)。
👉 挑戰:如果上一次運行後這個埠沒有完全釋放,再次啟動時就會遇到 Address already in use
錯誤。
👉 應對:需完全依賴 Colab 的「重新啟動並執行所有項目」功能,這能徹底清除舊的執行緒和被佔用的埠,確保每次啟動都是乾淨的。
2️⃣ 事件循環(Event Loop)衝突 🔄
Flask 伺服器和未來 Telegram Bot 的輪詢機制(Polling Mode)都會啟動自己的「事件循環」來監聽和處理訊息。
👉 挑戰:在同一個 Python 執行環境中,無法同時運行兩個獨立的事件循環,這會導致 RuntimeError: This event loop is already running
。
👉 應對:一個 Colab 筆記本只運行一個機器人服務。 本篇專注於 LINE Bot。如果後續要運行 Telegram Bot,請為其創建一個獨立的 Colab 筆記本,並在切換時重新啟動執行階段。
3️⃣ ngrok 隧道的管理 🔗
ngrok 負責將 Colab 內部運行的 Flask 伺服器公開到網際網路,讓 LINE 平台可以將訊息發送過來。
👉 挑戰:一個 ngrok 隧道只能指向一個正在運行的 Flask 應用程式。同時為多個機器人服務建立 Webhook,會使設置變得複雜且容易出錯。
👉 應對:延續「一個筆記本一個服務」的策略,每個機器人筆記本會各自啟動和管理自己的 ngrok 隧道。
4️⃣ 知識庫來源的處理 (PDF 已知問題) 📚
機器人需要知識庫來進行 RAG(檢索增強生成),最理想情況是從原始 PDF 文件中提取內容。
👉 挑戰:PDF 文件的解析和文本提取本身可能很複雜,且容易因格式問題而失敗,導致知識庫生成失敗。
👉 應對:在程式碼中,將優先嘗試從上傳的 PDF 檔案中提取內容。但為了確保每一次運行都能成功並有一個可用的知識庫,可以同時包含了一份內置的 SDGs 數據作為備用。如果 PDF 處理失敗或文件不存在,機器人依然可以運行並提供基礎的 SDGs 知識服務。這確保了程式的穩健性,讓你不用擔心因 PDF 問題而無法繼續。
if use_default_sdgs_data: #備用知識庫內容
chunks = [
"永續發展目標1:無貧窮。在世界各地消除一切形式的貧窮。",
"永續發展目標2:零飢餓。消除飢餓,實現糧食安全,改善營養並促進永續農業。",
"永續發展目標3:健康與福祉。確保健康的生活,促進各年齡層的福祉。",
"永續發展目標4:優質教育。確保包容和公平的優質教育,促進所有人的終身學習機會。",
"永續發展目標5:性別平等。實現性別平等,賦予所有婦女和女孩權力。",
"永續發展目標6:清潔飲水和衛生設施。確保所有人都能獲得和永續管理水和衛生設施。",
"永續發展目標7:經濟適用的清潔能源。確保所有人都能獲得價格合理、可靠和永續的現代能源。",
"永續發展目標8:體面工作和經濟成長。促進包容和永續的經濟增長、充分和生產性就業以及人人享有體面工作。",
"永續發展目標9:產業、創新和基礎設施。建設有韌性的基礎設施,促進包容和永續的工業化,並推動創新。",
"永續發展目標10:減少不平等。減少國家內部和國家之間的不平等。",
"永續發展目標11:永續城市和社區。使城市和人類住區具有包容性、安全、有韌性和永續性。",
"永續發展目標12:負責任消費和生產。確保永續的消費和生產模式。",
"永續發展目標13:氣候行動。採取緊急行動應對氣候變化及其影響。",
"永續發展目標14:水下生命。永續保育和利用海洋及海洋資源,以促進永續發展。",
"永續發展目標15:陸地生命。保護、恢復和促進永續利用陸地生態系統,永續管理森林,防治荒漠化,制止和扭轉土地退化,遏制生物多樣性喪失。",
"永續發展目標16:和平、正義與健全機構。促進和平、包容的社會以促進永續發展,為所有人提供訴諸司法的機會,並在各級建立有效、負責和包容的機構。",
"永續發展目標17:目標夥伴關係。加強執行手段,重振永續發展全球夥伴關係。"
]
print(f"使用備用 SDGs 數據。共生成 {len(chunks)} 個文本區塊。")
index_file = "sdgs_faiss.index" #FAISS索引檔案名稱
chunks_file = "stored_chunks.pkl" #原始文本塊儲存檔案名稱
if not os.path.exists(index_file) or not os.path.exists(chunks_file) or use_default_sdgs_data:
print("知識庫檔案不存在或將使用新數據,正在生成 Embedding 並建立 FAISS 索引,這可能需要一些時間...")
embeddings = [] #存放所有文本塊的 Embedding 向量
stored_chunks_for_creation = [] #存放實際用於建立索引的文本塊
for i, chunk in enumerate(chunks):
try:
embedding = get_embedding(chunk, task_type="RETRIEVAL_DOCUMENT")
embeddings.append(embedding)
stored_chunks_for_creation.append(chunk)
except Exception as e:
print(f"警告:第 {i} 塊文本生成 Embedding 失敗!錯誤:{e}")
logger.warning(f"Warning: Failed to get embedding for chunk {i}: {e}", exc_info=True)
continue #可以跳過失敗的文本塊
以下是整合所有必要組件,可以新增一份獨立的 ColabL 筆記本進行整合。
!pip install
指令安裝 faiss-cpu
、numpy
、google-generativeai
、flask
、line-bot-sdk
、pyngrok
和 pypdf2
。這些是進行向量檢索、AI 模型互動、Web 服務和 LINE 平台連接的基礎。import
語句,確保在後續步驟開始前,所有必要的模組都已被載入。GOOGLE_API_KEY
、LINE_CHANNEL_ACCESS_TOKEN
、LINE_CHANNEL_SECRET
和 NGROK_AUTHTOKEN
環境變數。這是確保程式能連接到 Google Gemini AI 模型、LINE 訊息平台和 ngrok 隧道的基礎。get_embedding()
函式將文字轉換為數字向量,這是 RAG 系統中檢索的基石。sdgs_faiss.index
和 stored_chunks.pkl
檔案,供後續使用。這是一個「一次性」的生成過程,除非檔案被刪除或需要更新知識庫,否則下次運行時會直接載入。generate_response()
函式:這是 RAG 的核心!它會將使用者問題與從知識庫中檢索到的相關文本(retrieved_chunks
)結合,創建一個包含指令和上下文的提示詞(prompt
),然後發送給 Gemini 模型以生成最終答案。get_rag_answer()
函式:整合整個 RAG 流程,包括將使用者問題向量化、在 FAISS 索引中檢索相似文本,最後呼叫 generate_response()
得到答案。LineBotApi
和 WebhookHandler
,它們是 LINE Bot SDK 的核心組件,用於處理 LINE 平台的簽名驗證和解析收到的訊息事件。/callback
路由:定義一個 Flask 路由,當 LINE 平台發送 Webhook 請求時,會自動調用這個路由。這個路由負責驗證請求的合法性,並將訊息轉交給 handler
處理。handle_text_message()
函式:這個函式是當 LINE 收到文字訊息時會被觸發的核心。它會提取使用者訊息,呼叫 RAG 核心邏輯獲取答案,並透過 line_bot_api.reply_message()
將答案回覆給使用者。pyngrok
連接到 ngrok 服務,將你的本地 Flask 伺服器映射到一個公開的 HTTPS URL。透過整合的學習單元,我能在 Colab 中完整運行 LINE 機器人。